#ifndef GAME_H
#define GAME_H
#include <iostream>
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include <SDL3_mixer/SDL_mixer.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <glm/glm.hpp>
#include <string>
#include <random>
#include "../core/asset_store.h"
class sprite_data;
class scene;
class player;
class game {
public:
    static game& instance() {
        static game _instance;
        return _instance;
    }
    void run();
    void ready(const char* title,glm::vec2 size);
    void clean();
    void update(float dt);
    void render();
    void handleEvents();
    void quit(){isRun = false;};

    void drawGrid(const glm::vec2& top_left, const glm::vec2& bottom_right,float grid_size,SDL_FColor color);
    void drawBoundray(const glm::vec2 &top_left, const glm::vec2 &bottom_right, 
        float bottom_wihth, SDL_FColor color);
    void drawPoint(const std::vector<glm::vec2>& points, glm::vec2 position,SDL_FColor color);
    void renderSprite(const sprite_data& sprite_data,const glm::vec2& position,const glm::vec2& size,const glm::vec2& mask=glm::vec2(1.0f));
    void renderFillCircle(const glm::vec2& position, const glm::vec2& size, float alpha);
    void renderHbar(const glm::vec2& position, const glm::vec2& size, float percent, SDL_FColor color);
    void renderVbar(const glm::vec2& , const glm::vec2& , float , SDL_FColor ){}
    TTF_Text* createText(const char* text,const char* font_path, int font_size = 16);
    void updateMouse();


    glm::vec2 const getScreenSize(){ return screen_size;}
    scene* const getCurrentScene(){return current_scene;};
    SDL_Renderer* const getRenderer(){return renderer;}
    assetStore* const getAssetStore(){return asset_store;}
    glm::vec2 const getMousePosition(){return mouse_position;}
    SDL_MouseButtonFlags const getMouseButton(){return mouse_buttons;}
    int const getEnemyCount(){return enemyCount;}
    void addEnemyCount(){enemyCount++;}
    void setScore(int score_);
    int const getScore(){return score;}
    void addScore(int score_);
    void setHighScore(int highscore_){this->highscore = highscore_;}
    int const getHighScore(){return highscore;}
    void changeScene(scene* scene_);
    void safeChangeScene(scene* scene_){next_scene = scene_;}

    void playMusic(const char* path,bool loop = true){Mix_PlayMusic(asset_store->getMusic(path), loop ? -1 : 1);}
    void playSound(const char* path){Mix_PlayChannel(-1, asset_store->getSound(path), 0);}
    void stopMusic(){Mix_HaltMusic();}
    void stopSound(){Mix_HaltChannel(-1);}
    void pauseMusic(){Mix_PauseMusic();}
    void pauseSound(){Mix_Pause(-1);}
    void resumeMusic(){Mix_ResumeMusic();}
    void resumeSound(){Mix_Resume(-1);}

    float randomFloat(float min, float max) {return std::uniform_real_distribution<float>(min, max)(gen); }
    int randomInt(int min, int max) {return std::uniform_int_distribution<int>(min, max)(gen); }
    glm::vec2 randomVec2(const glm::vec2& min, const glm::vec2& max) {return glm::vec2(randomFloat(min.x, max.x), randomFloat(min.y, max.y)); }
    glm::ivec2 randomIVec2(const glm::ivec2& min, const glm::ivec2& max) {return glm::ivec2(randomInt(min.x, max.x), randomInt(min.y, max.y)); }
    std::string loadTextFile(const char* path);

private:
    glm::vec2 screen_size = glm::vec2(1200, 800);
    glm::vec2 mouse_position = glm::vec2(0, 0);
    SDL_MouseButtonFlags mouse_buttons = 0;
    SDL_Window* window = nullptr;
    SDL_Renderer* renderer = nullptr;
    TTF_TextEngine* ttfEngine = nullptr;
    std::mt19937 gen = std::mt19937(std::random_device{}());
    assetStore* asset_store = nullptr;
    int enemyCount = 0;
    bool isRun = true;
    Uint64 FPS = 60;
    Uint64 frame_Delay = 0;
    scene *current_scene = nullptr ,*next_scene = nullptr;
    player* player = nullptr;
    int score = 0;
    int highscore = 0;
    game() {}
    //game(const game&) = delete;
    game(const game&) = delete;
    game& operator=(const game&) = delete;
};

#endif